package com.坦克大战.Tank_5;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

@SuppressWarnings("all")
/**
 * KeyListener 监听器，监听键盘事件的发生
 */
public class MyPanel extends JPanel implements KeyListener, Runnable {

    MyTank tank = null;
    /// 我的坦克
    Vector<EnemyTanks> enemyTanks = new Vector<>();
    /// 敌方坦克集合
    int enemyTanksNum = 3;
    /// 敌方坦克数量
    Vector<Bomb> bombs = new Vector<>();
    Image image1 = Toolkit.getDefaultToolkit().createImage("java-code/src/com/坦克大战/Tank_5/bomb_1.gif");
    /// 炸弹图片
    Image image2 = Toolkit.getDefaultToolkit().createImage("java-code/src/com/坦克大战/Tank_5/bomb_2.gif");
    /// 炸弹图片;
    Image image3 = Toolkit.getDefaultToolkit().createImage("java-code/src/com/坦克大战/Tank_5/bomb_3.gif");

    /// 炸弹图片;

    public MyPanel() {  /// 构造器创建坦克
    /// 创建我方坦克
        tank = new MyTank(750, 630, 10);  ///创建我方坦克，初始坐标和速度

        /// 创建敌方坦克
        for (int i = 0; i < enemyTanksNum; i++) {
            EnemyTanks enemyTank = new EnemyTanks(100 * (i + 1), 0, 10);  ///创建敌方坦克放到集合当中，初始坐标和速度
            enemyTanks.add(enemyTank);
            new Thread(enemyTank).start();  ///创建完敌方坦克就启动线程，让他移动
            Shoot shoot = new Shoot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirection());  ///创建敌方坦克的子弹，初始化一个
            enemyTank.EnemyTanksBullets.add(shoot);     ///添加一个坦克子弹到该坦克的子弹集合
            new Thread(shoot).start();
        }

    }

    /// 画图方法
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.darkGray);  ///背景颜色
        g.fillRect(0, 0, 1500, 700); ///铺满整个界面

        ///画我方坦克的方法；（画笔，x，y，颜色，方向）
        if (!tank.isLive) {

        } else {
            drawTank(g, tank.getX(), tank.getY(), 0, tank.getDirection());
        }

        /// 画敌方坦克
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTanks ETank = enemyTanks.get(i);
            if (ETank.isLive) {  ///如果存活就画，未存活就删除
                drawTank(g, ETank.getX(), ETank.getY(), 1, ETank.getDirection());  ///画敌方坦克的方法；（画笔，x，y，颜色，方向）
            }

        }

        ///循环重绘我方子弹

        for (int i = 0; i < tank.TankBullets.size(); i++) {
            Shoot shoot = tank.TankBullets.get(i);///取出我防坦克子弹，如果存活就画，为存货就删除
            if (shoot.isLive) { //如果子弹存在
                drawShoot(g, shoot.x, shoot.y, 0, shoot.direction); ///画子弹的方法
            } else {
                tank.TankBullets.remove(i);///未存活就删除
            }
            /// 碰撞检测，如果我方子弹击中敌人坦克就在 hitTank(shoot, enemyTank);中相应处理
            for (int j = 0; j < enemyTanks.size(); j++) {
                EnemyTanks enemyTank = enemyTanks.get(j);
                hitTank(shoot, enemyTank);
            }
        }


        ///循环重绘敌方子弹,
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTanks enemyTank = enemyTanks.get(i);///取出敌方每一个坦克，再取出每一个子弹绘画
            if (enemyTank.EnemyTanksBullets.size() == 0 && !enemyTank.isLive) { /// 如果坦克的子弹都没了且坦克死亡（isLive == false），就删除当前坦克；
                enemyTanks.remove(i);  ///删除坦克
                /// 如果删除完敌方坦克后，集合中没有坦克了，就输出敌方坦克全部阵亡；
                if (enemyTanks.size() == 0)
                    System.out.println("敌方坦克全部阵亡");
            }

            for (int j = 0; j < enemyTank.EnemyTanksBullets.size(); j++) {
                Shoot shoot = enemyTank.EnemyTanksBullets.get(j);///取出敌方坦克子弹，如果存活就画，为存货就删除
                if (shoot.isLive) { ///如果子弹存在
                    drawShoot(g, shoot.x, shoot.y, 1, shoot.direction);///画子弹的方法
                } else {
                    enemyTank.EnemyTanksBullets.remove(j);///为存活就删除子弹
                }
                /// 碰撞检测，循环遍历敌方每一个子弹，如果碰到了就将我方坦克生命状态改成false，不画在面板;
                if (shoot.isLive && tank.isLive) {
                    hitTank(shoot, tank);
                }


            }

        }

        /// 重绘炸弹
        for (int i = 0; i < bombs.size(); i++) {///遍历
            Bomb bomb = bombs.get(i);
            if (bomb.live > 6) {  /// 根据炸弹生命周期来画不同的图片
                g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);
            } else if (bomb.live > 3) {
                g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
            } else {
                g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
            }
            bomb.lifeDown();  ///life--
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (bomb.live <= 0) ///生命周期结束就删除
                bombs.remove(i);
        }
    }


    /**
     * @param g         画笔
     * @param x         横坐标
     * @param y         纵坐标
     * @param type      区分敌我的颜色数字
     * @param direction 区分方向 0向上，1向左 2向下 3向右
     */
    /// 画坦克方法
    public void drawTank(Graphics g, int x, int y, int type, int direction) {

        choiceTankColor(g, type);  ///选择坦克的颜色方法；
        choiceTankDirection(x, y, g, direction); ///绘制坦克以及方向的方法
    }

    /// 画子弹方法
    public void drawShoot(Graphics g, int x, int y, int type, int direction) {
        choiceTankColor(g, type);///用坦克的颜色代替子弹颜色；
        DrawBullets(x, y, g);///绘画子弹
    }


    @Override
    ///键盘事件监听方法
    public void keyPressed(KeyEvent e) {  //改变坐标和方向
        //根据按下的按钮 进行判断;
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            tank.moveLEFT();
        } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            tank.moveRIGHT(1500);
        } else if (e.getKeyCode() == KeyEvent.VK_UP) {
            tank.moveUP();
        } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            tank.moveDOWN(700);
        } else if (e.getKeyCode() == KeyEvent.VK_J) {
            if (tank.TankBullets.size() <= 5 && tank.isLive)   /// 限制同时只能有5个子弹 且 我方坦克还活着才能发射；
                tank.shootEnemyTank();              /// 创建子弹，放入集合，启动子弹移动线程

        }


        this.repaint();///改变完方向和坐标后，主动设置重绘，会主动调用paint方法，用新的x和y来重新画；

    }


    /// 暂时没用的2个方法；
    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    /// 选择坦克的颜色的方法
    public void choiceTankColor(Graphics g, int type) {
        switch (type) {
            case 0:
                g.setColor(Color.CYAN); ///自己的颜色
                break;
            case 1:
                g.setColor(Color.red);  ///敌人的颜色
                break;
        }
    }

    /// 绘制坦克方法
    public void choiceTankDirection(int x, int y, Graphics g, int direction) {
        //int width1 = 10,height1 = 60; //轮子尺寸
        //int width2 = 20,height2 = 40; //车舱尺寸
        //int r = 20; //盖子直径
        //x y 初始化为100
        switch (direction) { ///选择方向  0上1左2下3右
            case 0:
                g.fill3DRect(x, y, 10, 60, false);  ///左轮子
                g.fill3DRect(x + 10, y + 10, 20, 40, false);    ///中间坦克舱
                g.fill3DRect(x + 10 + 20, y, 10, 60, false);    ///右轮子
                g.drawLine(x + 10 + 10, y + 10 + 20, x + 10 + 10, y);  ///炮管线
                g.fillOval(x + 10, (y + 60 / 2) - 10, 20, 20);  ///盖子
                break;
            case 1:
                g.fill3DRect(x, y, 60, 10, false);  ///左轮子
                g.fill3DRect(x + 10, y + 10, 40, 20, false);    ///中间坦克舱
                g.fill3DRect(x, y + 10 + 20, 60, 10, false);    ///右轮子
                g.drawLine(x + 10 + 10, y + 10 + 10, x, y + 20);  ///炮管线
                g.fillOval(x + 30 - 10, y + 10, 20, 20);  ///盖子
                break;
            case 2:
                g.fill3DRect(x, y, 10, 60, false);  ///左轮子
                g.fill3DRect(x + 10, y + 10, 20, 40, false);    ///中间坦克舱
                g.fill3DRect(x + 10 + 20, y, 10, 60, false);    ///右轮子
                g.drawLine(x + 10 + 10, y + 10 + 20, x + 10 + 10, y + 60);  ///炮管线
                g.fillOval(x + 10, (y + 60 / 2) - 10, 20, 20);  ///盖子
                break;
            case 3:
                g.fill3DRect(x, y, 60, 10, false);  ///左轮子
                g.fill3DRect(x + 10, y + 10, 40, 20, false);    ///中间坦克舱
                g.fill3DRect(x, y + 10 + 20, 60, 10, false);    ///右轮子
                g.drawLine(x + 10 + 10, y + 10 + 10, x + 60, y + 20);  ///炮管线
                g.fillOval(x + 30 - 10, y + 10, 20, 20);  ///盖子
                break;
        }
    }

    /// 绘制子弹
    public void DrawBullets(int x, int y, Graphics g) {
        g.fillOval(x, y, 5, 5);
    }

    /// 刷新画板
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000 / 60);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            this.repaint();///重绘
        }
    }

    /// 碰撞检测
    public void hitTank(Shoot shoot, Tank Tank) {///判断子弹是否集中敌方坦克(坦克活着)；
        if (Tank.getDirection() % 2 == 0) {  ///上下方向的坦克
        /// 如果子弹碰到了敌方坦克，且坦克活着就让坦克和子弹死亡，添加炸弹，如果子弹碰到尸体（指该坦克死亡但该坦克的子弹还没死亡，坦克还会再集合，但不会画出来）这时就不能发生碰撞了
            if (shoot.x >= Tank.getX() && shoot.x < Tank.getX() + 40 && shoot.y >= Tank.getY() && shoot.y < Tank.getY() + 60 && Tank.isLive) {
                Tank.isLive = false;   ///坦克死亡
                shoot.isLive = false;       ///子弹死亡
                Bomb bomb = new Bomb(Tank.getX(), Tank.getY());  ///根据死亡坦克的坐标创建炸弹，添加到炸弹集合
                bombs.add(bomb);
            }
        } else {///左右方向的敌人坦克
            if (shoot.x >= Tank.getX() && shoot.x < Tank.getX() + 60 && shoot.y >= Tank.getY() && shoot.y < Tank.getY() + 40 && Tank.isLive) {
                Tank.isLive = false;   ///同理
                shoot.isLive = false;   ///同理
                Bomb bomb = new Bomb(Tank.getX(), Tank.getY()); ///同理
                bombs.add(bomb);///同理
            }
        }

    }
}
